package cn.miju.alipay.handler;

import cn.hutool.core.collection.CollUtil;
import cn.miju.alipay.properties.AlipayProperties;
import cn.miju.common.util.CamelCaseUtil;
import com.alibaba.fastjson2.JSONObject;
import com.alipay.api.*;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * <pre>
 * 业务类
 * </pre>
 *
 * @author zhuming
 * @version 1.0.0
 * @since 2023-02-28 11:29
 */
@Slf4j
public abstract class AbstractAlipayHandler<REQ, RESP> {

    /**
     * 请求参数前置处理
     * @param req 请求参数
     * @return 结果
     */
    public abstract AlipayRequest beforeRequest(REQ req);

    /**
     * 核心执行
     * @param req 请求参数
     * @return 结果
     */
    public abstract RESP doPlan(REQ req) throws AlipayApiException;

    /**
     * 响应参数后置处理
     * @param response 响应参数
     * @return 结果
     */
    public abstract RESP afterResponse(AlipayResponse response);

    /**
     * 创建支付宝支付客户端
     * @param alipayProperties 配置参数
     * @return 客户端实例
     */
    public AlipayClient createAlipayClient(AlipayProperties alipayProperties) {
        return new DefaultAlipayClient(alipayProperties.getServerUrl(),
                alipayProperties.getAppId(),
                alipayProperties.getAppPrivateKey(),
                AlipayConstants.FORMAT_JSON,
                AlipayConstants.CHARSET_UTF8,
                alipayProperties.getAlipayPublicKey(),
                AlipayConstants.SIGN_TYPE_RSA2);
    }
    /**
     * 添加自定义可选参数到请求参数类
     * @param bizContent 请求参数类
     * @param optionalReqParams 自定义可选请求参数
     */
    public void setOptionalReqParams(JSONObject bizContent, Map<String, Object> optionalReqParams) {
        if (CollUtil.isNotEmpty(optionalReqParams)) {
            Set<String> keySet = bizContent.keySet();
            if (CollUtil.isNotEmpty(keySet)) {
                keySet.forEach(key -> {
                    if (optionalReqParams.containsKey(key) || Objects.isNull(optionalReqParams.get(key))) {
                        optionalReqParams.remove(key);
                    }
                });
            }
            bizContent.putAll(optionalReqParams);
        }
    }
    /**
     * 获取自定义可选返回参数
     * @param respData 返回参数类
     * @param optionalRespParams 自定义可选返回参数
     */
    public Map<String, Object> getOptionalRespParams(Object respData, Set<String> optionalRespParams) {
        if (CollUtil.isNotEmpty(optionalRespParams)) {
            Map<String, Object> responseParams = Maps.newHashMap();
            optionalRespParams.forEach(key -> {
                try {
                    Field field = respData.getClass().getDeclaredField(CamelCaseUtil.snakeToCamel(key));
                    field.setAccessible(true);
                    String name = field.getName();
                    Object value = field.get(respData);
                    field.setAccessible(false);
                    responseParams.put(name, value);
                } catch (Exception e) {
                    log.error("解析参数失败！", e);
                }
            });
            return responseParams;
        }
        return Collections.emptyMap();
    }
}
